package ru.digitanoise.dnnotificationapi.service;

import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import ru.digitanoise.dnnotificationapi.model.dto.RequestSendCode;
import ru.digitanoise.dnutils.SystemEntity;

import java.util.Objects;

@Service
@RequiredArgsConstructor
@Slf4j
public class MailService {

    private final JavaMailSender javaMailSender;

    private static final String CONFIRM_TOKEN_SUBJECT = "Активируйте аккаунт";
    private static final String RESTORE_PASSWORD_TOKEN_SUBJECT = "Восстановление пароля";

    @Value("${mail.username}")
    private String mailFrom;
    @Value("${urls.confirm-token-url}")
    private String confirmTokenUrl;
    @Value("${urls.restore-password-code-url}")
    private String restorePasswordCodeUrl;


    public void send(RequestSendCode requestSendCode) {
        if (Objects.equals(requestSendCode.getSystemType(), SystemEntity.ACTIVE_ACCOUNT)) {
            trySendTokenActive(requestSendCode);
        }
        if (Objects.equals(requestSendCode.getSystemType(), SystemEntity.CHANGE_PASSWORD)) {
            trySendTokenRestorePassword(requestSendCode);
        }
    }

    @Async
    public void trySendTokenRestorePassword(RequestSendCode requestSendCode) {
        try {
            sendMessage(
                    requestSendCode.getMailAccount(),
                    RESTORE_PASSWORD_TOKEN_SUBJECT,
                    buildRestorePasswordCodeMsg(requestSendCode.getCode())
            );
        }
        catch (Exception e) {
            log.info("Cant send token. Token is " + requestSendCode.getMailAccount() + " : " + requestSendCode.getCode());
        }
    }

    private String buildRestorePasswordCodeMsg(String token) {
        return "<a href=\"" + restorePasswordCodeUrl +
                "?token=" + token +
                "\">Создание нового пароля<a/>";
    }

    @Async
    public void trySendTokenActive(RequestSendCode requestSendCode) {
        try {
            sendMessage(
                    requestSendCode.getMailAccount(),
                    CONFIRM_TOKEN_SUBJECT,
                    buildConfirmCodeMsg(requestSendCode.getCode())
            );
        }
        catch (Exception e) {
            log.info("Cant send token. Token is " + requestSendCode.getMailAccount() + " : " + requestSendCode.getCode());
        }
    }

    private String buildConfirmCodeMsg(String token) {
        return "<a href=\"" + confirmTokenUrl +
                "?token=" + token +
                "\">Подтвердить регистрацию<a/>";
    }

    public void sendMessage(String email, String subject, String msg) {
        MimeMessage mimeMailMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMailMessage, "UTF-8");

        try {
            helper.setFrom(mailFrom);
            helper.setTo(email);
            helper.setSubject(subject);
            helper.setText(msg, true);
            javaMailSender.send(mimeMailMessage);
        }
        catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }
}
